﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Jelly2013.Entity;
using System.Threading;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;
using Jelly2013.Query;
using System.Net;

namespace Jelly2013
{
    public partial class Form_Order_Add : Form
    {
        [DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool InternetSetCookie(string lpszUrlName, string lbszCookieName, string lpszCookieData);
        TicketInfo _TicketInfo;
        bool _AutoOrder;
        BindingList<Passenger> ordersPassengers = new BindingList<Passenger>();
        List<KeyValuePair<string, string>> SeatTypies = new List<KeyValuePair<string, string>>();
        List<KeyValuePair<string, string>> PassengerTypies = new List<KeyValuePair<string, string>>();
        
        public Form_Order_Add(TicketInfo tInfo,bool autoOrder)
        {
            InitializeComponent();
            _TicketInfo = tInfo;
            _AutoOrder = autoOrder;
            Thread.CurrentThread.ApartmentState = ApartmentState.STA;
        }

        private void UIInit()
        {
            Init_Page(_TicketInfo);
            getVerificationCode(null);
            initPassenger();
            initDgvOrder();
            if (_AutoOrder)
            {
                DoAutoOrder();
            }
        }

        private void DoAutoOrder()
        {
            List<Passenger> passengers = getPassenger();
            foreach (Passenger item in passengers)
            {
                if (SeatTypies.Count < 1)
                {
                    item.SeatType = "-1";
                }
                else
                {
                    item.SeatType = Macth_SeatType();
                }
            }
            Orders.Passengers = passengers;
            Orders.TicketInfo = _TicketInfo;
            Orders.TrainDate = Orders.TicketInfo.TrainDate;
            try
            {
                string msg = string.Empty;
                bool result = SubmitOrder.DoSubmitOrder(Orders, txtVerificationCode.Text, ref msg);
                MessageBox.Show(msg);
                openIE();
                this.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "异常", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                this.Close();
            }
        }

        private string Macth_SeatType()
        {
            foreach (SeatType item in Form_Main._SelectedList_SeatType)
            {
                foreach (KeyValuePair<string,string> temp in SeatTypies)
                {
                    if (temp.Value == item.ToString())
                    {
                        return temp.Key;
                    }
                }
            }
            return "-1";
        }

        private void Show_TextInfo(string htmlStr)
        {
            lblTrainInfo.Text = _TicketInfo.TrainDate +_TicketInfo.StationTrainCode+ "        " + _TicketInfo.DepartureStation + "（" + _TicketInfo.DrivingTime + "开）        " + _TicketInfo.DestinationStation + "（" + _TicketInfo.ArrivalTime + "到）        历时（" + _TicketInfo.ElapsedTime + "）";
            //TODO:
            htmlStr=htmlStr.Substring(htmlStr.IndexOf("class=\"bluetext\">历时")+19);
            htmlStr = htmlStr.Substring(htmlStr.IndexOf("<tr>")+4);
            htmlStr = htmlStr.Substring(0,htmlStr.IndexOf(@"</tr>"));
            htmlStr = htmlStr.Replace("<td>", string.Empty).Replace(Environment.NewLine, string.Empty);
            htmlStr = htmlStr.Replace(@"</td>", "        ");
            htmlStr = htmlStr.Trim();
            lblSeateInfo.Text = htmlStr;
        }

        private void Init_Page(TicketInfo ticketInfo)
        {
            List<KeyValuePair<string, string>> postData = new List<KeyValuePair<string, string>>();
            postData.Add(new KeyValuePair<string, string>("station_train_code", ticketInfo.StationTrainCode));
            postData.Add(new KeyValuePair<string, string>("train_date",ticketInfo.TrainDate));
            postData.Add(new KeyValuePair<string, string>("seattype_num", string.Empty));
            postData.Add(new KeyValuePair<string, string>("from_station_telecode", ticketInfo.DepartureStationTelCode));
            postData.Add(new KeyValuePair<string, string>("to_station_telecode", ticketInfo.DestinationStationTelCode));
            postData.Add(new KeyValuePair<string, string>("include_student", "00"));
            postData.Add(new KeyValuePair<string, string>("from_station_telecode_name", ticketInfo.DepartureStation));
            postData.Add(new KeyValuePair<string, string>("to_station_telecode_name", ticketInfo.DestinationStation));
            postData.Add(new KeyValuePair<string, string>("round_train_date", ticketInfo.TrainDate));
            postData.Add(new KeyValuePair<string, string>("round_start_time_str", "00:00--24:00"));
            postData.Add(new KeyValuePair<string, string>("single_round_type", "1"));//单程 1 返程 2
            postData.Add(new KeyValuePair<string, string>("train_pass_type", "QB"));
            postData.Add(new KeyValuePair<string, string>("train_class_arr", "QB#"));
            postData.Add(new KeyValuePair<string, string>("start_time_str", "00:00--24:00"));
            postData.Add(new KeyValuePair<string, string>("lishi", ticketInfo.ElapsedTime));
            postData.Add(new KeyValuePair<string, string>("train_start_time", ticketInfo.DrivingTime));
            postData.Add(new KeyValuePair<string, string>("trainno4", ticketInfo.TrainNo));
            postData.Add(new KeyValuePair<string, string>("arrive_time", ticketInfo.ArrivalTime));
            postData.Add(new KeyValuePair<string, string>("from_station_name", ticketInfo.DepartureStation));
            postData.Add(new KeyValuePair<string, string>("to_station_name", ticketInfo.DestinationStation));
            postData.Add(new KeyValuePair<string, string>("ypInfoDetail", ticketInfo.InfoDetail));
            postData.Add(new KeyValuePair<string, string>("mmStr", ticketInfo.MmStr));
            postData.Add(new KeyValuePair<string, string>("locationCode", ticketInfo.LocationCode));
            postData.Add(new KeyValuePair<string, string>("from_station_no", ticketInfo.From_station_no));
            postData.Add(new KeyValuePair<string, string>("to_station_no", ticketInfo.To_station_no));
            try
            {
                string webResult;
                string submutOrderRequestUrl = "https://dynamic.12306.cn/otsweb/order/querySingleAction.do?method=submutOrderRequest";

                while (true)
                {
                    webResult = CommUitl.postString(submutOrderRequestUrl, postData, null, null, Encoding.UTF8, CommData.cookieCollection, "https://dynamic.12306.cn/otsweb/order/querySingleAction.do?method=init");
                    if (webResult.IndexOf("系统忙") == -1)
                    {
                        break;
                    }
                }
                string message = getMessage(webResult);
                if (!string.IsNullOrEmpty(message))
                {
                    MessageBox.Show(message);
                }
                else
                {
                    Show_TextInfo(webResult);
                    InitSeatType(webResult);
                    InitPassengerTypies(webResult);
                    Orders.Left_ticket = Get_Left_ticket(webResult);
                    Orders.Token = Get_Token(webResult);
                    //string token = getToken(webResult);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "异常", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
                this.Close();
            }
        }

        private string Get_Token(string str)
        {
            str = str.Substring(str.IndexOf("org.apache.struts.taglib.html.TOKEN\"") + 37);
            str = str.Substring(str.IndexOf("\"") + 1);
            str = str.Substring(0, str.IndexOf("\""));
            return str;
        }
        private static string Get_Left_ticket(string str)
        {
            str = str.Substring(str.IndexOf("id=\"left_ticket\"") + 17);
            str = str.Substring(str.IndexOf("\"") + 1);
            str = str.Substring(0, str.IndexOf("\""));
            //{"end_station_name":"","end_time":"","id":"2","start_station_name":"","start_time":"","value":"软座"},{"end_station_name":"","end_time":"","id":"1","start_station_name":"","start_time":"","value":"硬座"}
            return str;
        }
        private void InitPassengerTypies(string webResult)
        {
            webResult = webResult.Substring(webResult.IndexOf("var limitBuySeatTicketDTO =") + 27);
            webResult = webResult.Substring(webResult.IndexOf("ticket_type_codes") + 18);
            webResult = webResult.Substring(webResult.IndexOf("[") + 1);
            webResult = webResult.Substring(0, webResult.IndexOf("]"));
            //{"end_station_name":"","end_time":"","id":"2","start_station_name":"","start_time":"","value":"软座"},{"end_station_name":"","end_time":"","id":"1","start_station_name":"","start_time":"","value":"硬座"}
            webResult = webResult.Replace("\"", string.Empty);
            string[] items = webResult.Split(new string[] { "}" }, StringSplitOptions.RemoveEmptyEntries);
            foreach (string item in items)
            {
                if (!item.Contains("value"))
                {
                    continue;
                }
                string[] temp = item.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                PassengerTypies.Add(new KeyValuePair<string, string>(temp[2].Split(':')[1], temp[5].Split(':')[1]));
            }
        }
        private void InitSeatType(string webResult)
        {
            webResult = webResult.Substring(webResult.IndexOf("var limitBuySeatTicketDTO =") + 27);
            webResult = webResult.Substring(webResult.IndexOf("[") + 1);
            webResult = webResult.Substring(0, webResult.IndexOf("]"));
            //{"end_station_name":"","end_time":"","id":"2","start_station_name":"","start_time":"","value":"软座"},{"end_station_name":"","end_time":"","id":"1","start_station_name":"","start_time":"","value":"硬座"}
            webResult = webResult.Replace("\"", string.Empty);
            string[] items = webResult.Split(new string[] { "}" }, StringSplitOptions.RemoveEmptyEntries);
            foreach (string item in items)
            {
                if (!item.Contains("value"))
                {
                    continue;
                }
                string[] temp = item.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                SeatTypies.Add(new KeyValuePair<string, string>(temp[2].Split(':')[1], temp[5].Split(':')[1]));
            }
        }
        private void initDgvOrder()
        {
            dgvOrder.AutoGenerateColumns = false;
            dgvOrder.RowHeadersVisible = false;
            dgvOrder.AllowUserToAddRows = false;

            DataGridViewLinkColumn dgvlcDelete = new DataGridViewLinkColumn();
            dgvlcDelete.UseColumnTextForLinkValue = true;
            dgvlcDelete.Name = "dgvlcDelete";
            dgvlcDelete.Text = "删除";
            dgvlcDelete.HeaderText = "删除";
            dgvlcDelete.Width = 50;
            dgvOrder.Columns.Add(dgvlcDelete);

            DataGridViewComboBoxColumn dgvcbcSeatType = new DataGridViewComboBoxColumn();
            dgvcbcSeatType.Name = "dgvcbcSeatType";
            dgvcbcSeatType.DataPropertyName = "SeatType";
            dgvcbcSeatType.DataSource = SeatTypies;
            dgvcbcSeatType.ValueMember = "key";
            dgvcbcSeatType.DisplayMember = "value";
            dgvcbcSeatType.HeaderText = "席别";
            dgvcbcSeatType.Width = 80;
            dgvOrder.Columns.Add(dgvcbcSeatType);

            DataGridViewComboBoxColumn dgvcbcSeatDetail = new DataGridViewComboBoxColumn();
            dgvcbcSeatDetail.Name = "dgvcbcSeatDetail";
            dgvcbcSeatDetail.DataPropertyName = "Seat_detail";
            dgvcbcSeatDetail.DataSource = Get_Seat_detail();
            dgvcbcSeatDetail.ValueMember = "key";
            dgvcbcSeatDetail.DisplayMember = "value";
            dgvcbcSeatDetail.HeaderText = "铺位";
            dgvcbcSeatDetail.Width = 80;
            dgvOrder.Columns.Add(dgvcbcSeatDetail);

            DataGridViewComboBoxColumn dgvcbcPassengerTicket = new DataGridViewComboBoxColumn();
            dgvcbcPassengerTicket.Name = "dgvcbcPassengerTicket";
            dgvcbcPassengerTicket.DataPropertyName = "PassengerTicket";
            dgvcbcPassengerTicket.DataSource = PassengerTypies;
            dgvcbcPassengerTicket.ValueMember = "key";
            dgvcbcPassengerTicket.DisplayMember = "value";
            dgvcbcPassengerTicket.HeaderText = "票种";
            dgvcbcPassengerTicket.Width = 80;
            dgvOrder.Columns.Add(dgvcbcPassengerTicket);

            DataGridViewTextBoxColumn dgvtbcName = new DataGridViewTextBoxColumn();
            dgvtbcName.Name = "dgvtbcName";
            dgvtbcName.DataPropertyName = "Name";
            dgvtbcName.HeaderText = "姓名";
            dgvtbcName.Width = 60;
            dgvOrder.Columns.Add(dgvtbcName);

            DataGridViewTextBoxColumn dgvtbcCardNo = new DataGridViewTextBoxColumn();
            dgvtbcCardNo.Name = "dgvtbcCardNo";
            dgvtbcCardNo.DataPropertyName = "CardNo";
            dgvtbcCardNo.HeaderText = "证件号码";
            dgvtbcCardNo.Width = 140;
            dgvOrder.Columns.Add(dgvtbcCardNo);

            DataGridViewTextBoxColumn dgvtbcMobileNo = new DataGridViewTextBoxColumn();
            dgvtbcMobileNo.Name = "dgvtbcMobileNo";
            dgvtbcMobileNo.DataPropertyName = "MobileNo";
            dgvtbcMobileNo.HeaderText = "手机号";
            dgvtbcMobileNo.Width = 100;
            dgvOrder.Columns.Add(dgvtbcMobileNo);

            dgvOrder.CellContentClick += new DataGridViewCellEventHandler(dgvOrder_CellContentClick);

            dgvOrder.DataSource = Form_Main._SelectedList_Passengers;
            foreach (DataGridViewRow dr in dgvOrder.Rows)
            {
                dr.Cells[1].Value = Macth_SeatType();
            }
        }

        private object Get_Seat_detail()
        {
            List<KeyValuePair<string, string>> result = new List<KeyValuePair<string, string>>();
            result.Add(new KeyValuePair<string, string>("0", "随机"));
            result.Add(new KeyValuePair<string, string>("3", "上铺"));
            result.Add(new KeyValuePair<string, string>("2", "中铺"));
            result.Add(new KeyValuePair<string, string>("1", "下铺"));
            return result;
        }
        void dgvOrder_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.ColumnIndex == 0)
            {
                dgvOrder.Rows.RemoveAt(e.RowIndex);
            }
        }
        #region 初始化旅客信息
        
        private void initPassenger()
        {
            List<Passenger> list = Passenger_Query.List;
            pnlPassenger.Controls.Clear();
            Point p = new Point(20, 50);
            for (int i = 0; i < list.Count; i++)
            {
                Passenger item = list[i];
                CheckBox chkbox = new CheckBox();
                chkbox.Name = "chk" + item.CardNo;
                chkbox.Text = item.Name;
                chkbox.Tag = item;
                chkbox.AutoSize = true;
                chkbox.CheckedChanged += new EventHandler(chkbox_CheckedChanged);
                p.X = i % 8 * 80 + 5;
                if (i % 8 == 0)
                {
                    p.X = 25;
                    p.Y = i / 5 * 25;
                }
                chkbox.Location = p;
                pnlPassenger.Controls.Add(chkbox);
            }
        }
        void chkbox_CheckedChanged(object sender, EventArgs e)
        {
            if (dgvOrder.RowCount > 4)
            {
                MessageBox.Show("一次订票最多添加【5】名乘客！");
                return;
            }
            CheckBox chkbox = sender as CheckBox;
            Passenger passenger = chkbox.Tag as Passenger;
            if (chkbox.Checked == true)
            {
                ordersPassengers.Add(passenger);
            }
            else
            {
                ordersPassengers.Remove(passenger);
            }
            dgvOrder.DataSource = ordersPassengers;
        }

        #endregion

        #region Get
        private string getMessage(string webResult)
        {
            string result = string.Empty;
            string keyword = "var message = \"";
            int startInt = webResult.IndexOf(keyword, 0);
            if (startInt > -1)
            {
                startInt += keyword.Length; ;
                int endInt = webResult.IndexOf("\";", startInt);
                result = webResult.Substring(startInt, endInt - startInt);
            }
            return result;
        }
        private string getTicketInfo(string webResult)
        {
            string result = string.Empty;
            int startInt;
            string keyword = "<tr style=\"background-color:#F3F8FC\">";
            startInt = webResult.IndexOf(keyword);
            if (startInt > -1)
            {
                startInt += keyword.Length;
                int endInt;
                endInt = webResult.IndexOf("以上余票信息随时发生变化，仅作参考", startInt);
                result = webResult.Substring(startInt, endInt);
                result = CommUitl.ReplaceHTMLAttributes(webResult.Substring(startInt, endInt - startInt)).Replace("\r\n", string.Empty).Replace("\t", string.Empty);
                Regex re = new Regex(@"[/s]{2,}", RegexOptions.Compiled);
                result = Regex.Replace(result.Trim(), "\\s+", " ");
            }
            return result;
        }
        /// <summary>
        /// 得到Token
        /// </summary>
        /// <param name="webResult"></param>
        /// <returns></returns>

        #endregion
        private void Form_Order_Add_Load(object sender, EventArgs e)
        {
            UIInit();
        }
        #region 验证码
        int count = 0;
        /// <summary>
        /// 得到验证码 外部调用
        /// </summary>
        /// <param name="obj"></param>
        private void getVerificationCode(object obj)
        {
            picValidImg.Image = null;
            count = 0;
            setVerificationCode();
        }

        /// <summary>
        /// 得到验证码 内部重复调用 直到得到验证码
        /// </summary>
        private void setVerificationCode()
        {
            count++;
            string url = url = "https://dynamic.12306.cn/otsweb/passCodeAction.do?rand=randp";
            try
            {
                picValidImg.Image = CommUitl.getVerificationCode(url, CommData.cookieContainer, CommData.cookieCollection, "https://dynamic.12306.cn/otsweb/order/confirmPassengerAction.do?method=init");
                try
                {
                    txtVerificationCode.Text = new FuckCaptcha.Service_Captcha().Get_CaptchaCode(picValidImg.Image as Bitmap);
                }
                catch (Exception ex)
                {
                    if (count > 5)
                    {
                        return;
                    }
                    setVerificationCode();
                }
            }
            catch (Exception ex)
            {
                setVerificationCode();
            }
        }
        #endregion
        #region 提交订单
        OrderInfo orders;
        OrderInfo Orders
        {
            get
            {
                if (orders == null)
                {
                    orders = new OrderInfo();
                }
                return orders;
            }
            set
            {
                orders = value;
            }
        }
        private void btnSubmit_Click(object sender, EventArgs e)
        {
            if (!Validate_Submit())
            {
                return;
            }
            List<Passenger> passengers = getPassenger();
            Orders.Passengers = passengers;
            Orders.TicketInfo = _TicketInfo;
            Orders.TrainDate = Orders.TicketInfo.TrainDate;
            try
            {
                string msg = string.Empty;
                bool result = SubmitOrder.DoSubmitOrder(Orders, txtVerificationCode.Text, ref msg);
                MessageBox.Show(msg);
                openIE();
                this.Close();
            }
            catch (Exception ex)
            {
                getVerificationCode(null);
                MessageBox.Show(ex.Message, "下单失败", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
            }
        }
        private List<Passenger> getPassenger()
        {
            List<Passenger> result=new List<Passenger>();
            foreach (DataGridViewRow dr in dgvOrder.Rows)
            {
                Passenger p = dr.DataBoundItem as Passenger;
                p.SeatType = dr.Cells[1].Value.ToString();
                p.Seat_detail = dr.Cells[2].Value.ToString();
                p.PassengerTicket = dr.Cells[3].Value.ToString();
                result.Add(p);
            }
            return result;
        }
        private bool Validate_Submit()
        {
            if (dgvOrder.Rows.Count < 1)
            {
                MessageBox.Show("请选择乘客！");
                return false;
            }
            foreach (DataGridViewRow dr in dgvOrder.Rows)
            {
                if (dr.Cells[1] == null || dr.Cells[1].Value == null || string.IsNullOrEmpty(dr.Cells[1].Value.ToString()))
                {
                    MessageBox.Show("请为所有乘客选择席别！");
                    return false;
                }
            }
            return true;
        }
        private void openIE()
        {
            foreach (Cookie cookie in CommData.cookieContainer.GetCookies(new Uri("https://dynamic.12306.cn/otsweb/loginAction.do?method=login")))
            {
                InternetSetCookie(
                    "https://" + cookie.Domain.ToString(),
                    cookie.Name.ToString(),
                    cookie.Value.ToString() + ";expires=Sun,22-Feb-2099 00:00:00 GMT");
            }
            string url = "https://dynamic.12306.cn/otsweb/";
            System.Diagnostics.Process.Start("IExplore.exe", url);
        }
        #endregion

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void dgvOrder_DataError(object sender, DataGridViewDataErrorEventArgs e)
        {
            Thread.CurrentThread.ApartmentState = ApartmentState.STA;
            if ((e.ColumnIndex == 1 || e.ColumnIndex == 2) && e.Exception is ArgumentException)
            {
                e.Cancel = true;
            }
        }
    }
}
